package com.lxd.milktea.service.impl;

import com.lxd.milktea.dao.MaterialReRepository;
import com.lxd.milktea.dao.MaterialRepository;
import com.lxd.milktea.dataobject.Material;
import com.lxd.milktea.dataobject.MaterialRe;
import com.lxd.milktea.service.MaterialService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ProjectName: milktea
 * @Package: com.lxd.milktea.service.impl
 * @ClassName: MaterialServiceImpl
 * @Author: carrymaniac
 * @Description:
 * @Date: 2020/5/3 2:08 下午
 * @Version:
 */
@Service
public class MaterialServiceImpl implements MaterialService {
    @Autowired
    MaterialRepository materialRepository;

    @Autowired
    MaterialReRepository materialReRepository;

    @Override
    public Material findOne(String materialId) {
        Optional<Material> material = materialRepository.findById(materialId);
        if (material.isPresent()){
            return material.get();
        }else {
            //todo
            return null;
        }
    }

    @Override
    public HashMap<String, Integer> findOneForm(String materialId) {
        /**
         * 查找过程：
         *  拿到ID查找对应的一级原料关系图，压入队列中去
         *  遍历队列，取出队列里的项ID，去关系表查询对应的子材料
         *  当查询不到子材料时 说明为最终材料。将其放入到结果集
         *
         */
        LinkedList<MaterialRe> allByMId = materialReRepository.findAllByMaterialId(materialId);
        LinkedList<HashMap<String, Object>> queue = new LinkedList<>();
        HashMap<String, Integer> result = new HashMap<>();;
        if(allByMId.isEmpty()){
            result.put(materialId,1);
            return result;
        }
        allByMId.stream().forEach(materialRe -> {
            HashMap<String, Object> map = new HashMap();
            map.put("mid",materialRe.getSonMaterialId());
            map.put("num",materialRe.getNeedNum());
            queue.add(map);
        });

        while (!queue.isEmpty()){
            HashMap<String, Object> p = queue.poll();
            String mid = (String) p.get("mid");
            Integer num = (Integer)p.get("num");
            LinkedList<MaterialRe> next = materialReRepository.findAllByMaterialId(mid);
            if(!next.isEmpty()){
                next.stream().forEach(materialRe -> {
                    HashMap<String, Object> map = new HashMap();
                    map.put("mid",materialRe.getSonMaterialId());
                    map.put("num",materialRe.getNeedNum()*num);
                    queue.push(map);
                });
            }else {
                if(result.get(mid)!=null){
                    result.put(mid,result.get(mid)+num);
                }else{
                    result.put(mid,num);
                }
            }
        }
        return result;
    }

    @Override
    public Map<String, Integer> findOneSon(String materialId) {
        LinkedList<MaterialRe> allByMId = materialReRepository.findAllByMaterialId(materialId);
        return allByMId.stream().collect(Collectors.toMap(MaterialRe::getSonMaterialId, MaterialRe::getNeedNum));
    }

    @Override
    public Material save(Material materialId) {
        return materialRepository.save(materialId);
    }

    @Override
    public List<Material> findList(List<String> ids) {
        return materialRepository.findAllByIdIn(ids);
    }

    @Override
    public Page<Material> findList(Pageable pageable) {
        Page<Material> all = materialRepository.findAll(pageable);
        return all;
    }

    @Override
    public List<Material> findAll() {
        return  materialRepository.findAll();
    }

    @Override
    public void deleteMaterialRe(String materialId) {
        materialReRepository.deleteAllByMaterialId(materialId);
    }

    @Override
    public List<MaterialRe> saveMaterialRe(String material, List<com.lxd.milktea.form.MaterialRe> list) {
        List<MaterialRe> collect = list.stream().map(m -> {
            MaterialRe materialRe = new MaterialRe();
            materialRe.setMaterialId(material);
            materialRe.setSonMaterialId(m.getMaterialId());
            materialRe.setNeedNum(m.getNum());
            return materialRe;
        }).collect(Collectors.toList());
        return materialReRepository.saveAll(collect);
    }
}
